﻿using System;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Windows.Forms;

namespace Directory
{
  /// <summary>
  /// ドメイン関連情報画面のフォームです。
  /// </summary>
  internal sealed partial class DomainInfo : Form
  {
    #region プライベートフィールド
    private readonly Domain adDomain;
    #endregion

    #region パブリックコンストラクター
    /// <summary>
    /// ドメインを指定して DomainInfo クラスの新しいインスタンスを初期化します。
    /// </summary>
    /// <param name="domain">ドメイン。</param>
    /// <exception cref="ArgumentNullException"><paramref name="domain"/> が null です。</exception>
    public DomainInfo(Domain domain)
    {
      if (domain == null)
      {
        throw new ArgumentNullException("domain", "domain が null です。");
      }

      InitializeComponent();

      adDomain = domain;
      this.ShowInfo();  //ドメイン関連情報を表示
    }
    #endregion

    #region イベントハンドラ
    private void GCListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
      this.GCSiteLabel.Text = ((GlobalCatalog)this.GCListBox.SelectedItem).SiteName;
    }

    private void SiteListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
      var site = (ActiveDirectorySite)this.SiteListBox.SelectedItem;
      this.ServerListBox.DataSource = site.Servers.Cast<DirectoryServer>().ToList();
      this.SiteLinkListBox.DataSource = site.SiteLinks.Cast<ActiveDirectorySiteLink>().ToList();
      this.SubnetListBox.DataSource = site.Subnets;
    }

    private void SiteLinkListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
      var siteLink = (ActiveDirectorySiteLink)this.SiteLinkListBox.SelectedItem;
      this.CostLabel.Text = siteLink.Cost.ToString();
      this.RepliLabel.Text = siteLink.ReplicationInterval.ToString();
      this.TransportLabel.Text = siteLink.TransportType.ToString();
    }

    private void DCListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
      var dc = adDomain.DomainControllers[this.DCListBox.SelectedIndex];
      this.OSLabel.Text = dc.OSVersion;
      this.IPLabel.Text = dc.IPAddress;
      this.DCSiteLabel.Text = dc.SiteName;
    }
    #endregion

    #region プライベートメソッド
    /// <summary>
    /// ドメイン関連情報を表示します。
    /// </summary>
    private void ShowInfo()
    {
      var forest = adDomain.Forest;   //フォレスト
      this.ForestLabel.Text = forest.Name;
      this.ForestModeLabel.Text = forest.ForestMode.ToString();
      this.RootDomainLabel.Text = forest.RootDomain.Name;
      foreach (GlobalCatalog gc in forest.GlobalCatalogs)
      {
        this.GCListBox.Items.Add(gc);
      }
      this.GCListBox.SelectedIndex = 0;
      foreach (Domain domain in forest.Domains)
      {
        this.DomainListBox.Items.Add(domain);
      }

      foreach (ActiveDirectorySite site in forest.Sites)    //サイト
      {
        this.SiteListBox.Items.Add(site);
      }
      this.SiteListBox.SelectedIndex = 0;

      this.DomainLabel.Text = adDomain.Name;    //ドメイン
      this.DomainModeLabel.Text = adDomain.DomainMode.ToString();
      foreach (DomainController dc in adDomain.DomainControllers)
      {
        this.DCListBox.Items.Add(dc.Name.Substring(0, dc.Name.IndexOf('.')));
      }
      this.DCListBox.SelectedIndex = 0;

      this.SchemaLabel.Text = forest.SchemaRoleOwner.Name;    //FSMO
      this.NamingLabel.Text = forest.NamingRoleOwner.Name;
      this.RIDLabel.Text = adDomain.RidRoleOwner.Name;
      this.PDCLabel.Text = adDomain.PdcRoleOwner.Name;
      this.InfraLabel.Text = adDomain.InfrastructureRoleOwner.Name;
    }
    #endregion
  }
}
